package ee.ts022.tuum.dao;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;


@Repository
public abstract class DomainDao {
	
	private static final Logger logger = LoggerFactory.getLogger(DomainDao.class);
	
	@Autowired
	protected SessionFactory sessionFactory;
	private Class<?> domainClass;
	private String idFieldName;
	
	public DomainDao(Class<?> domainClass) {
		this.domainClass = domainClass;
		
		for (Field field : domainClass.getDeclaredFields()) {
			if(idFieldName != null){
				break;
			}
			
			Annotation[] annotations = field.getDeclaredAnnotations();
			for(Annotation annotation : annotations){
			    if(annotation instanceof javax.persistence.Id){
			    	idFieldName = field.getName();
			    	break;
			    }
			}
		}
	}
	
	
	@SuppressWarnings("unchecked")
	protected <T> List<T> getAllDomain() {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(domainClass);
		return (List<T>) criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	protected <T> T getDomain(int id) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(domainClass);
		criteria.add(Restrictions.eq(idFieldName, id));
		return (T) criteria.uniqueResult();
	}
	
	protected <T> boolean saveDomain(T domain) {
		try {
			sessionFactory.getCurrentSession().saveOrUpdate(domain);
			return true;
		} catch (HibernateException e) {
			logger.error(e.getMessage());
			return false;
		}
	}


	public <T> boolean insertDomain(T domain) {
		try {
			sessionFactory.getCurrentSession().save(domain);
			return true;
		} catch (HibernateException e) {
			logger.error(e.getMessage());
			return false;
		}
	}


	public <T> boolean deleteDomain(T domain) {
		try {
			sessionFactory.getCurrentSession().delete(domain);
			return true;
		} catch (HibernateException e) {
			logger.error(e.getMessage());
			return false;
		}
	}
}
